import { Module, NestModule, MiddlewareConsumer, RequestMethod } from '@nestjs/common'
import { ConfigModule, ConfigService } from '@nestjs/config'

// import { CacheModule } from '@nestjs/cache-manager';
import { ThrottlerModule } from '@nestjs/throttler'
// import { ScheduleModule } from '@nestjs/schedule';
// import { EventEmitterModule } from '@nestjs/event-emitter';
// import { BullModule } from '@nestjs/bull';
import { MulterModule } from '@nestjs/platform-express'
import { ServeStaticModule } from '@nestjs/serve-static'
import { RedisModule } from '@liaoliaots/nestjs-redis'
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core'
import { ValidationPipe } from '@nestjs/common'
import { join } from 'path'
// import * as redisStore from 'cache-manager-redis-store';

// 配置
import { databaseConfig } from './config/database.config'
import { redisConfig } from './config/redis.config'
import { jwtConfig } from './config/jwt.config'
import { fileConfig } from './config/file.config'
import { emailConfig } from './config/email.config'
import { loggerConfig } from './config/logger.config'

// 模块
import { AuthModule } from './auth/auth.module'
import { UserModule } from './user/user.module'
import { ContentModule } from './content/content.module'
import { CategoryModule } from './category/category.module'
import { FileModule } from './file/file.module'
import { SystemModule } from './system/system.module'
import { HealthModule } from './health/health.module'

// 控制器
import { AppController } from './app.controller'
import { AppService } from './app.service'

// 守卫
import { JwtAuthGuard } from './modules/auth/guards/jwt-auth.guard'
import { RolesGuard } from './modules/auth/guards/roles.guard'
import { ThrottlerGuard } from '@nestjs/throttler'

// 拦截器
import { ResponseTransformInterceptor } from './common/interceptors/response.interceptor'
import { LoggingInterceptor } from './common/interceptors/logging.interceptor'
// import { CacheInterceptor } from '@nestjs/cache-manager';

// 过滤器
import { HttpExceptionFilter, GlobalExceptionFilter } from './common/filters/http-exception.filter'

// 中间件
import {
  RequestLoggerMiddleware,
  SecurityHeadersMiddleware,
  CorsMiddleware,
  RequestIdMiddleware,
  ResponseTimeMiddleware,
  UserAgentMiddleware,
  RealIpMiddleware,
  ContentTypeMiddleware,
  RequestSizeMiddleware,
  HealthCheckMiddleware,
  MaintenanceMiddleware
} from './common/middleware/global.middleware'

// 服务
import { LoggerService } from './logger/logger.service'

@Module({
  imports: [
    // 配置模块
    ConfigModule.forRoot({
      isGlobal: true,
      load: [databaseConfig, redisConfig, jwtConfig, fileConfig, emailConfig, loggerConfig],
      envFilePath: ['.env.local', '.env'],
      cache: true
    }),

    // Redis模块
    RedisModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        config: {
          host: configService.get('redis.host'),
          port: configService.get('redis.port'),
          password: configService.get('redis.password'),
          db: configService.get('redis.db'),
          retryDelayOnFailover: configService.get('redis.retryDelayOnFailover'),
          enableReadyCheck: configService.get('redis.enableReadyCheck'),
          maxRetriesPerRequest: configService.get('redis.maxRetriesPerRequest')
        }
      }),
      inject: [ConfigService]
    }),

    // 缓存模块
    // CacheModule.registerAsync({
    //   imports: [ConfigModule],
    //   useFactory: (configService: ConfigService) => ({
    //     store: redisStore,
    //     host: configService.get('redis.host'),
    //     port: configService.get('redis.port'),
    //     password: configService.get('redis.password'),
    //     db: configService.get('redis.db'),
    //     ttl: configService.get('redis.ttl'),
    //     max: configService.get('redis.max'),
    //     isGlobal: true,
    //   }),
    //   inject: [ConfigService],
    // }),

    // 限流模块
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        throttlers: [
          {
            ttl: 60000, // 时间窗口（毫秒）
            limit: 100 // 请求限制
          }
        ]
      }),
      inject: [ConfigService]
    }),

    // 任务调度模块
    // ScheduleModule.forRoot(),

    // 事件模块
    // EventEmitterModule.forRoot({
    //   wildcard: false,
    //   delimiter: '.',
    //   newListener: false,
    //   removeListener: false,
    //   maxListeners: 10,
    //   verboseMemoryLeak: false,
    //   ignoreErrors: false,
    // }),

    // 队列模块
    // BullModule.forRootAsync({
    //   imports: [ConfigModule],
    //   useFactory: (configService: ConfigService) => ({
    //     redis: {
    //       host: configService.get('redis.host'),
    //       port: configService.get('redis.port'),
    //       password: configService.get('redis.password'),
    //       db: configService.get('redis.db') + 2, // 使用不同的数据库
    //     },
    //     defaultJobOptions: {
    //       removeOnComplete: 10,
    //       removeOnFail: 5,
    //       attempts: 3,
    //       backoff: {
    //         type: 'exponential',
    //         delay: 2000,
    //       },
    //     },
    //   }),
    //   inject: [ConfigService],
    // }),

    // 文件上传模块
    MulterModule.registerAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        dest: configService.get('file.uploadPath'),
        limits: {
          fileSize: configService.get('file.maxSize'),
          files: configService.get('file.maxFiles')
        }
      }),
      inject: [ConfigService]
    }),

    // 静态文件服务
    ServeStaticModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => [
        {
          rootPath: join(__dirname, '..', configService.get('file.staticPath')),
          serveRoot: '/static',
          exclude: ['/api*']
        },
        {
          rootPath: join(__dirname, '..', 'uploads'),
          serveRoot: '/uploads',
          exclude: ['/api*']
        }
      ],
      inject: [ConfigService]
    }),

    // 业务模块
    AuthModule,
    UserModule,
    ContentModule,
    CategoryModule,
    FileModule,
    SystemModule,
    HealthModule
  ],
  controllers: [AppController],
  providers: [
    // 核心服务
    AppService,
    LoggerService,

    // 全局验证管道
    {
      provide: APP_PIPE,
      useClass: ValidationPipe
    },

    // 全局守卫
    {
      provide: APP_GUARD,
      useClass: ThrottlerGuard
    },

    // 全局拦截器
    {
      provide: APP_INTERCEPTOR,
      useClass: ResponseTransformInterceptor
    },
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor
    },

    // 全局异常过滤器
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter
    },
    {
      provide: APP_FILTER,
      useClass: GlobalExceptionFilter
    },

    // 中间件
    RequestLoggerMiddleware,
    SecurityHeadersMiddleware,
    CorsMiddleware,
    RequestIdMiddleware,
    ResponseTimeMiddleware,
    UserAgentMiddleware,
    RealIpMiddleware,
    ContentTypeMiddleware,
    RequestSizeMiddleware,
    HealthCheckMiddleware,
    MaintenanceMiddleware
  ]
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    // 维护模式中间件 - 最高优先级
    consumer.apply(MaintenanceMiddleware).forRoutes({ path: '*', method: RequestMethod.ALL })

    // 健康检查中间件
    consumer
      .apply(HealthCheckMiddleware)
      .forRoutes({ path: '/health', method: RequestMethod.GET })
      .apply(HealthCheckMiddleware)
      .forRoutes({ path: '/ping', method: RequestMethod.GET })

    // 安全相关中间件
    consumer.apply(SecurityHeadersMiddleware).forRoutes({ path: '*', method: RequestMethod.ALL })

    // CORS中间件
    consumer.apply(CorsMiddleware).forRoutes({ path: '*', method: RequestMethod.ALL })

    // 请求处理中间件
    consumer
      .apply(
        RequestIdMiddleware,
        ResponseTimeMiddleware,
        RealIpMiddleware,
        UserAgentMiddleware,
        RequestLoggerMiddleware
      )
      .forRoutes({ path: '*', method: RequestMethod.ALL })

    // 内容验证中间件
    consumer
      .apply(ContentTypeMiddleware)
      .forRoutes(
        { path: '/api/*', method: RequestMethod.POST },
        { path: '/api/*', method: RequestMethod.PUT },
        { path: '/api/*', method: RequestMethod.PATCH }
      )

    // 请求大小限制中间件
    consumer
      .apply(RequestSizeMiddleware)
      .forRoutes(
        { path: '/api/*', method: RequestMethod.POST },
        { path: '/api/*', method: RequestMethod.PUT },
        { path: '/api/*', method: RequestMethod.PATCH }
      )
  }
}
